home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
magazine
/
lantimes
/
90_03
/
tserv.c
< prev
next >
Wrap
Text File
|
1990-01-08
|
11KB
|
399 lines
/*-------------------------------------------------------------------------*
* tserv.c -- Tnet server program
*
* One computer in this network is designated the server machine. This
* program runs on that machine and only terminates in response
* to a keyboard request (``esc'' key) or a remote ``kill'' request.
* Network events are used to exchange data between the server and
* a remote node, and to control the operation of the server.
*
* T. Nolan - 11/20/89
*-------------------------------------------------------------------------*/
#include <dos.h>
#include <process.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "netbios.h"
#include "network.h"
static char buf[4096]; /* buffer for file read/write */
int verbose; /* set to 1 for diagnostic output */
int exitflag; /* set to 1 to cause program exit */
char local[16]; /* name of local network node */
/*-------------------------------------------------------------------------*/
main(int ac, char **av)
{
NCB ncblist[SESSIONS];
ACTION actlist[SESSIONS];
int i;
if(!get_name(local)) /* find node name */
{
printf("error - NetBios not running\n");
exit(1);
}
/* Issue receive datagrams on all of the ncbs. */
for(i = 0; i < SESSIONS; i++)
{
clear_ncb(&ncblist[i]);
nw_recv_datagram(&actlist[i], sizeof(ACTION), &ncblist[i]);
}
printf( "Tnet Server - T. Nolan 11/20/89 running on node %s\n", local);
/* This is the main event loop. Any action results in
* an event appearing on the event list. Here it is
* dequeued, dispatched, and placed back on its free list.
*/
while(!exitflag)
{
if(kbhit())
key_handler(getch());
for(i = 0; i < SESSIONS; i++)
{
if(ncblist[i].cmdcplt != 0xff)
{
net_handler(&ncblist[i], &actlist[i]);
clear_ncb(&ncblist[i]);
nw_recv_datagram(&actlist[i], sizeof(ACTION), &ncblist[i]);
}
}
}
/* Cancel all outstanding netbios requests and exit. */
for(i = 0; i < SESSIONS; i++)
nb_cancel(&ncblist[i]);
exit(0);
}
/*-------------------------------------------------------------------------*/
key_handler(int keych) /* handle local keyboard action */
{
switch(tolower(keych))
{
case '\033' :
exitflag = 1;
break;
case 'v' :
verbose = !verbose;
if(verbose)
diag("verbose mode\n");
break;
default :
diag("unrecognized key char %x\n", keych);
break;
}
}
/*-------------------------------------------------------------------------*/
net_handler(NCB *ncb, ACTION *cmd) /* handle network action */
{
char *node = ncb->callname; /* point to remote requesting node */
switch(cmd->type)
{
case NET_CNCT :
net_cnct(node, cmd);
break;
case NET_GET :
net_get(node, cmd);
break;
case NET_PUT :
net_put(node, cmd);
break;
case NET_DIR :
net_dir(node, cmd);
break;
case NET_CHD :
net_chd(node, cmd);
break;
case NET_DEL :
net_del(node, cmd);
break;
case NET_REMOTE :
net_remote(node, cmd);
break;
case NET_BYE :
exitflag = 1;
break;
default :
printf("Unrecognized network command type %d\n",cmd->type);
cmd->code = NET_ERR;
send_datagram(node, cmd, sizeof(ACTION));
break;
}
}
/*-------------------------------------------------------------------------*/
diag(a, b, c, d, e, f, g, h, i, j) /* diagnostic output */
{
if(!verbose)
return; /* only in verbose mode */
printf((char *) a, b, c, d, e, f, g, h, i, j);
}
/*-------------------------------------------------------------------------*/
net_cnct(char *node, ACTION *cmd) /* accept a remote connection */
{
diag("net_cnct %s\n", node);
cmd->code = NET_ACK;
strncpy(cmd->name, node, 16);
send_datagram(node, cmd, sizeof(ACTION));
}
/*-------------------------------------------------------------------------*/
net_get(char *node, ACTION *cmd) /* handle request to get files */
{
FILE *fp;
int lsn = 0;
int len;
struct find_t info;
int found;
char fname[80];
char *dir_end;
diag("net_get file %s node %s\n", cmd->name, node);
found = !_dos_findfirst(cmd->name, 0, &info);
strcpy(fname, cmd->name); /* copy file name */
dir_end = strrchr(fname, '\\'); /* locate last '\' char */
if(!dir_end) /* none there... */
dir_end = fname; /* so no directory string */
else /* otherwise.. */
dir_end++; /* point one char past '\' */
while(found)
{
cmd->size = info.size; /* extract file size */
strcpy(cmd->name, info.name); /* send name w/o directory */
*dir_end = '\0'; /* prepare to concat fname */
strcat(fname, info.name); /* .. onto end of dir string */
if((fp = fopen(fname, "rb")) == NULL) /* now open the file */
{
diag("can't open file %s\n", fname);
break;
}
cmd->code = NET_ACK;
send_datagram(node, cmd, sizeof(ACTION));
diag("sending file %s", fname);
while(!lsn)
lsn = call(node, local);
while(cmd->size > 0)
{
diag(".");
len = fread(buf, 1, sizeof(buf), fp);
send(lsn, buf, len);
cmd->size -= len;
}
fclose(fp);
diag("\n");
found = !_dos_findnext(&info);
receive(lsn, 0, 0); /* wait for ACK */
}
cmd->code = NET_ERR;
send_datagram(node, cmd, sizeof(ACTION));
receive(lsn, 0, 0); /* wait for hangup */
}
/*-------------------------------------------------------------------------*/
net_put(char *node, ACTION *cmd) /* handle request to put files */
{
FILE *fp;
int lsn = 0;
int len;
diag("net_put file %s size %ld node %s\n", cmd->name, cmd->size, node);
fp = fopen(cmd->name, "wb");
if(!fp)
{
diag("error opening file\n");
cmd->code = NET_ERR;
send_datagram(node, cmd, sizeof(ACTION));
return;
}
cmd->code = NET_ACK;
send_datagram(node, cmd, sizeof(ACTION));
while(!lsn)
lsn = call(node, local);
diag("receiving file %s", cmd->name);
while(cmd->size > 0)
{
diag(".");
len = receive(lsn, buf, sizeof(buf));
if(fp)
fwrite(buf, 1, len, fp);
cmd->size -= len;
}
diag("\n");
fclose(fp);
hangup(lsn);
}
/*-------------------------------------------------------------------------*/
net_chd(char *node, ACTION *cmd) /* handle req to change dir */
{
int ret = 0;
int dum;
char *cp;
int drive;
diag("net_chd: path %s\n", cmd->name);
cp = strchr(cmd->name, ':'); /* locate drive specifier, if any */
if(cp) /* if there is one.. */
{
drive = toupper(cp[-1]) - 'A' + 1;
_dos_setdrive(drive, &dum); /* set the drive */
if(cp[1]) /* if there is a directory spec... */
ret = chdir(cmd->name); /* set the directory too */
}
else
if(*cmd->name) /* no drive, but a directory... */
ret = chdir(cmd->name); /* set the directory */
getcwd(cmd->name, sizeof(cmd->name)); /* now get current directory */
cmd->code = (ret) ? NET_ERR : NET_ACK; /* set success or error flag */
send_datagram(node, cmd, sizeof(ACTION)); /* send cwd back */
}
/*-------------------------------------------------------------------------*/
net_dir(char *node, ACTION *cmd) /* handle directory request */
{
char *tmpfile;
char *dos;
char arg[80];
FILE *fp;
int len;
int lsn = 0;
diag("net_dir: node=%s, cmd=%s\n",node, cmd->name);
tmpfile = tempnam(NULL,"tnet"); /* make unique name */
strcpy(arg, "dir/w "); /* form a command... */
strcat(arg, cmd->name); /* of the form */
strcat(arg, ">"); /* dir file > tmp */
strcat(arg, tmpfile);
dos = getenv("COMSPEC"); /* find command.com */
spawnl(P_WAIT, dos, dos, "/C", arg, NULL); /* spawn w/ cmd line */
if((fp = fopen(tmpfile, "rb")) == NULL) /* open temp file */
{
printf("can't open %s\n",tmpfile); /* something's wrong */
cmd->code = NET_ERR; /* nak the request */
send_datagram(node, cmd, sizeof(ACTION));
return;
}
cmd->size = filelength(fileno(fp)); /* get dir length */
cmd->code = NET_ACK; /* ack the request */
send_datagram(node, cmd, sizeof(ACTION));
while(!lsn)
lsn = call(node, local); /* call remote node */
while(cmd->size > 0) /* send the file */
{
len = fread(buf, 1, sizeof(buf), fp);
send(lsn, buf, len);
cmd->size -= len;
}
fclose(fp); /* close it */
unlink(tmpfile); /* delete it */
receive(lsn, 0, 0); /* wait for hang up */
}
/*-------------------------------------------------------------------------*/
net_del(char *node, ACTION *cmd) /* handle req to delete files */
{
struct find_t info;
int found;
char *c;
int nfiles = 0;
char cwd[60], fname[70];
diag("net_del file %s node %s\n", cmd->name, node);
c = strrchr(cmd->name,'\\');
if(c)
strncpy(cwd, cmd->name, c - cmd->name);
else
cwd[0]='\0';
found = !_dos_findfirst(cmd->name, _A_NORMAL, &info);
while(found)
{
strcpy(fname, cwd);
strcat(fname, info.name);
printf("unlinking %s\n",fname);
if(!unlink(fname))
nfiles++;
found = !_dos_findnext(&info);
}
cmd->code = (nfiles) ? NET_ACK : NET_ERR;
cmd->size = nfiles; /* send # files deleted */
send_datagram(node, cmd, sizeof(ACTION));
}
/*-------------------------------------------------------------------------*/
net_remote(char *node, ACTION *cmd) /* req to execute command */
{
int i;
int ac;
char *av[10];
char *bp;
av[0] = getenv("COMSPEC"); /* 1st arg is command.com pathname */
av[1] = "/C"; /* 2nd arg is /C (transient command) */
ac = cmd->size + 2; /* fill in command args */
for(i = 2, bp = cmd->name; i < ac; i++)
{
av[i] = bp;
bp += strlen(bp) + 1;
}
av[ac] = 0; /* terminate parameter list */
diag("net_remote node=%s ac=%d", node, ac);
for(i = 0; i < ac; i++)
diag(" %s", av[i]);
cmd->code = spawnv(P_WAIT, av[0], av); /* issue command */
send_datagram(node, cmd, sizeof(ACTION)); /* return exit code */
}